using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Web;
using System.IO;
using System.Collections;

namespace Web.Ajax.Reflection
{
    public class Assembly
    {
        public static DateTime GetAssemblyBuildTime(System.Reflection.Assembly a)
        {
            HttpContext c = HttpContext.Current;
 
            DateTime AssemblyBuildTime = DateTime.Now;
            if (a == null)
                return AssemblyBuildTime;

            object o = null;
            if(c!=null)
                o=c.Application["Web.Ajax.BuildTime"];
            if (o is DateTime)
            {
                AssemblyBuildTime = (DateTime)o;
            }
            else
            {
                FileInfo f = new FileInfo(a.Location);
                if (f.Exists)
                {
                    AssemblyBuildTime = f.LastWriteTime;
                    if(c!=null)
                        c.Application["Web.Ajax.BuildTime"] = AssemblyBuildTime;
                }
            }
            return AssemblyBuildTime;
        }

        private static System.Reflection.Assembly ThisAssembly;
        private static string[] Resources;

        private static System.Reflection.Assembly[] BinAssemblies;
        private static Hashtable BinAssemlyResources = new Hashtable();
        private static System.Reflection.Assembly[] GetBinAssemblies()
        {
            System.Reflection.Assembly a=ThisAssembly;

#if !DEBUG
            if (BinAssemblies != null)
                return BinAssemblies;
#endif
            List<System.Reflection.Assembly> list = new List<System.Reflection.Assembly>();
            if (System.Web.HttpContext.Current == null)
                return list.ToArray();

            string bin=System.Web.HttpContext.Current.Server.MapPath("~/bin");
            DirectoryInfo d = new DirectoryInfo(bin);
            FileInfo[] files = d.GetFiles();
            for (int i = 0; i < files.Length; i++)
            {
                string name=files[i].Name;
                if (name==("Web.Ajax.Styles.dll"))
                {
                    System.Reflection.Assembly ba=System.Reflection.Assembly.LoadFile(files[i].FullName);
                    if (a.FullName != ba.FullName)
                    {
                        BinAssemlyResources[ba.FullName] = ba.GetManifestResourceNames();
                        list.Add(ba);
                    }
                }
            }
            //No longer caching Assemblies when debug is defined as it's a pain in dev.
#if !DEBUG
            BinAssemblies=list.ToArray();
            return BinAssemblies;
#endif
            return list.ToArray();
        }

        public static System.Reflection.Assembly SearchBinAssemblies(string ResourceName)
        {
            System.Reflection.Assembly[] bin=GetBinAssemblies();

            for (int i = 0; i < bin.Length; i++)
            {
                string n = bin[i].FullName;
                string[] resources = (string[])BinAssemlyResources[n];
                for (int j = 0; j < resources.Length; j++)
                {
                    if (resources[j] == ResourceName)
                        return bin[i];
                }
            }
            return null;
        }

        public static System.Reflection.Assembly GetAssembly(string ResourceName)
        {
            if (ThisAssembly == null)
            {
                ThisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
                Resources = ThisAssembly.GetManifestResourceNames();
            }
            for (int i = 0; i < Resources.Length; i++)
            {
                if (Resources[i] == ResourceName)
                    return ThisAssembly;
            }
            System.Reflection.Assembly a=SearchBinAssemblies(ResourceName);
            if (a != null)
                return a;
            throw new Exception("Resource not in any know Assembly '"+ResourceName+"'");
        }
    }
}
